using System;
using System.Collections.Generic;
using System.Drawing;

namespace HslControls.GameSupport
{
	/// <summary>
	/// 坦克大战的游戏引擎
	/// </summary>
	public class TankEngine : ClassicGameEngine
	{
		private MoveGameItem userTank;

		private List<MoveGameItem> bullets;

		private List<MoveGameItem> enemies;

		private List<MoveGameItem> enemyBullets;

		private int eliminateCount = 0;

		/// <summary>
		/// 玩家的坦克
		/// </summary>
		public MoveGameItem UserTank => userTank;

		/// <summary>
		/// 游戏结束的信息
		/// </summary>
		public Action OnGameOver
		{
			get;
			set;
		}

		/// <summary>
		/// 过去被消灭的数量
		/// </summary>
		public int GetEliminateCount => eliminateCount;

		/// <summary>
		/// 只用指定的长宽来实例化游戏对象
		/// </summary>
		/// <param name="pixelCol">列数</param>
		/// <param name="pixelRow">行数</param>
		public TankEngine(int pixelCol, int pixelRow)
			: base(pixelCol, pixelRow)
		{
			userTank = CreateTankFromPosition(new Point(base.PixelCol / 2 - 1, 0));
			userTank.PaintColor = Color.Blue;
			bullets = new List<MoveGameItem>();
			enemies = new List<MoveGameItem>();
			enemyBullets = new List<MoveGameItem>();
			for (int i = 10; i < 30; i++)
			{
				gameArrays[i, 8].HasItem = true;
				gameArrays[i, 8].ItemColor = Color.Tomato;
			}
			CreateRandomEnemies();
		}

		/// <summary>
		/// 判断当前的点位数据是否有碰撞情况
		/// </summary>
		/// <param name="points">等待检测的点位数据</param>
		/// <returns>是否有碰撞的情况</returns>
		private bool OnMoveTankSuccess(Point[] points)
		{
			for (int i = 0; i < points.Length; i++)
			{
				if (points[i].X >= 0 && points[i].X < base.PixelCol && points[i].Y >= 0 && points[i].Y < base.PixelRow)
				{
					if (gameArrays[points[i].X, points[i].Y].HasItem)
					{
						return false;
					}
					continue;
				}
				return false;
			}
			return true;
		}

		/// <summary>
		/// 判断当前的点位数据是否有碰撞情况
		/// </summary>
		/// <param name="points">等待检测的点位数据</param>
		/// <returns>是否有碰撞的情况</returns>
		private bool OnMoveBulletSuccess(Point[] points)
		{
			for (int i = 0; i < points.Length; i++)
			{
				if (points[i].X >= 0 && points[i].X < base.PixelCol && points[i].Y >= 0 && points[i].Y < base.PixelRow)
				{
					if (gameArrays[points[i].X, points[i].Y].HasItem)
					{
						return false;
					}
					continue;
				}
				return false;
			}
			return true;
		}

		/// <summary>
		/// 额外绘制的内容
		/// </summary>
		/// <param name="g">绘制对象</param>
		protected override void DrawCustomer(Graphics g)
		{
			base.DrawCustomer(g);
			DrawGameItem(g, userTank);
			for (int k = 0; k < enemies.Count; k++)
			{
				DrawGameItem(g, enemies[k]);
			}
			for (int j = bullets.Count - 1; j >= 0; j--)
			{
				DrawGameItem(g, bullets[j]);
			}
			for (int i = enemyBullets.Count - 1; i >= 0; i--)
			{
				DrawGameItem(g, enemyBullets[i]);
			}
		}

		/// <summary>
		/// 点击了向左的按钮
		/// </summary>
		public void MoveLeft()
		{
			if (!userTank.TurnLeft())
			{
				userTank.MoveLeft();
			}
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 点击了向右的按钮
		/// </summary>
		public void MoveRight()
		{
			if (!userTank.TurnRight())
			{
				userTank.MoveRight();
			}
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 点击了向上的按钮
		/// </summary>
		public void MoveUp()
		{
			if (!userTank.TurnUp())
			{
				userTank.MoveUp();
			}
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 点击了向下的按钮
		/// </summary>
		public void MoveDown()
		{
			if (!userTank.TurnDown())
			{
				userTank.MoveDown();
			}
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 通过位置创建一个坦克对象
		/// </summary>
		/// <param name="position">位置信息</param>
		/// <returns>坦克对象</returns>
		public MoveGameItem CreateTankFromPosition(Point position)
		{
			return new MoveGameItem(new Point[6]
			{
				new Point(0, 0),
				new Point(0, 1),
				new Point(1, 1),
				new Point(1, 2),
				new Point(2, 1),
				new Point(2, 0)
			}, position, new Size(base.PixelCol, base.PixelRow), OnMoveTankSuccess);
		}

		/// <summary>
		/// 通过坦克信息创建一个子弹对象
		/// </summary>
		/// <param name="tank">坦克对象</param>
		/// <returns>子弹对象</returns>
		public MoveGameItem CreateBulletFromTank(MoveGameItem tank)
		{
			Point position = default(Point);
			switch (tank.Direction)
			{
			case 0:
				position = new Point(tank.Location.X + 1, tank.Location.Y + 2);
				break;
			case 1:
				position = new Point(tank.Location.X + 2, tank.Location.Y + 1);
				break;
			case 2:
				position = new Point(tank.Location.X + 1, tank.Location.Y);
				break;
			case 3:
				position = new Point(tank.Location.X, tank.Location.Y + 1);
				break;
			}
			return new MoveGameItem(new Point[1]
			{
				new Point(0, 0)
			}, position, new Size(base.PixelCol, base.PixelRow), OnMoveBulletSuccess)
			{
				Direction = tank.Direction,
				PaintColor = tank.PaintColor
			};
		}

		/// <summary>
		/// 创建用户坦克的子弹信息
		/// </summary>
		public void CreateUserBullet()
		{
			MoveGameItem bullet = CreateBulletFromTank(userTank);
			bullets.Add(bullet);
		}

		/// <summary>
		/// 移动所有的子弹信息
		/// </summary>
		public void MoveBullet()
		{
			for (int i = bullets.Count - 1; i >= 0; i--)
			{
				if (!bullets[i].MoveNext())
				{
					bullets.RemoveAt(i);
				}
				else
				{
					for (int k = enemies.Count - 1; k >= 0; k--)
					{
						if (enemies[k].IsPositionInMoveItem(bullets[i].GetActualPoints()))
						{
							enemies.RemoveAt(k);
							bullets.RemoveAt(i);
							eliminateCount++;
							break;
						}
					}
				}
			}
			for (int j = enemyBullets.Count - 1; j >= 0; j--)
			{
				if (!enemyBullets[j].MoveNext())
				{
					enemyBullets.RemoveAt(j);
				}
				else if (userTank.IsPositionInMoveItem(enemyBullets[j].GetActualPoints()))
				{
					OnGameOver?.Invoke();
				}
			}
			OnBitmapShow(GetRenderBitmap());
		}

		private bool IsAreaEmpty(int col)
		{
			for (int i = 0; i < enemies.Count; i++)
			{
				if (enemies[i].Location.X > col - 3 && enemies[i].Location.X < col + 3 && enemies[i].Location.Y > base.PixelRow - 3)
				{
					return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 批量创建敌方的坦克信息
		/// </summary>
		public void CreateRandomEnemies(int count = 100)
		{
			int count_now = 0;
			for (int i = 0; i < base.PixelCol - 3; i += 3)
			{
				if (IsAreaEmpty(i))
				{
					MoveGameItem enemy = CreateTankFromPosition(new Point(i, base.PixelRow - 3));
					enemy.TurnDown();
					enemies.Add(enemy);
					count_now++;
				}
				if (count_now > count)
				{
					break;
				}
			}
		}

		/// <summary>
		/// 移除初始的保护
		/// </summary>
		public void RemoveProtection()
		{
			for (int i = 10; i < 30; i++)
			{
				gameArrays[i, 8].HasItem = false;
			}
		}

		/// <summary>
		/// 所有的敌方坦克放子弹
		/// </summary>
		public void EnemyFire()
		{
			for (int i = 0; i < enemies.Count; i++)
			{
				MoveGameItem bullet = CreateBulletFromTank(enemies[i]);
				enemyBullets.Add(bullet);
			}
		}

		/// <summary>
		/// 敌方坦克随机移动
		/// </summary>
		public void EnemyMoveRandom()
		{
			for (int i = 0; i < enemies.Count; i++)
			{
				enemies[i].MoveRandom();
			}
		}

		/// <summary>
		/// 获取敌方坦克数量
		/// </summary>
		/// <returns></returns>
		public int GetEnemyCount()
		{
			return enemies.Count;
		}
	}
}
